<template>
  <canvas id="three"></canvas>

</template>

<script>
import * as THREE from "three";
import {OrbitControls} from "three/examples/jsm/controls/OrbitControls";
import {initThree} from "../utils/enviromentUtil";
export default {
  // 光线投射
  name: "rayCasting",
  data() {
    return {
      scene: '',
      renderer: "",
      camera: "",
      orbitControls: "",

    }
  },
  mounted() {
    this.initThree()
    this.initSphereGeometries()
    this.playAnimation()
    this.listenMouseLocation()
  },
  methods: {
    initThree() {

      initThree.call(this)
    },

    initSphereGeometries() {

      function createSphere(color) {
        let sphere = new THREE.SphereGeometry(20)

        let material = new THREE.MeshBasicMaterial({
          color
        })

        return new THREE.Mesh(sphere, material);

      }


      let s1 = createSphere(0x110000)
      let s2 = createSphere(0x00ff00)
      let s3 = createSphere(0xff00ff)

      s1.position.x = -60
      s2.position.x = 0
      s3.position.x = 60

      this.scene.add(s1)
      this.scene.add(s2)
      this.scene.add(s3)
    },


    playAnimation() {
      const animate = () => {

        this.renderer.render(this.scene, this.camera)

        this.orbitControls.update()

        requestAnimationFrame(animate)
      }
      animate()
    },

    listenMouseLocation() {

      let rayCaster = new THREE.Raycaster()

      window.addEventListener('click', e => {

        // 对鼠标的坐标进行归一化
        let normalizedX = e.clientX / window.innerWidth
        let normalizedY = e.clientY / window.innerHeight

        // 归一化到 [-1,1] 之间
        normalizedX = normalizedX * 2 - 1
        normalizedY = -(normalizedY * 2 - 1)

        console.log(e.clientX, e.clientY, normalizedX, normalizedY)

        // 归一化之后的鼠标位置向量
        let normalizedMouseLocationVector = new THREE.Vector2(normalizedX, normalizedY)

        // 通过相机和鼠标的位置来更新射线
        rayCaster.setFromCamera(normalizedMouseLocationVector, this.camera)

        this.scene.children.filter(object3d => {
          return object3d.isMesh
        }).filter(mesh => {
          return rayCaster.intersectObject(mesh, false).length > 0
        }).forEach(mesh => {
          if (mesh._isClicked) {

            mesh.material.color.copy(mesh._originalColor)
            mesh._isClicked = false
          } else {
            mesh._originalColor = mesh.material.color.clone()

            mesh._isClicked = true
            mesh.material.color.set(0xff0000)
          }

        })

      })
    }
  }
}
</script>

<style scoped>
#three {
  width: 100%;
  height: 100%;
}
</style>
